import type { IPanelItem } from "@ibiz/model-core";
import {
  type IPanelItemController,
  ScriptFactory,
} from "@ibiz-template/runtime";
import { isArray, isObject, isString, kebabCase } from "lodash-es";
import pagesJson from "@/pages.json";

/**
 * 获取指定条件的所有页面
 * - 如果未指定key，则表示所有的pages，如果传递了 key, 则表示通过 key-value 过滤
 * @param key
 * @param value
 * @returns
 */
export const getAllPages = (
  key = "needLogin",
  value: string | number | boolean | undefined | null
) => {
  // 这里处理主包
  const pages = [
    ...(pagesJson.pages as IData[])
      .filter((page) => !key || page[key] === value)
      .map((page) => ({
        ...page,
        path: `/${page.path}`,
      })),
  ];
  // 这里处理分包
  const subPages: any[] = [];
  pagesJson.subPackages.forEach((subPageObj: IData) => {
    const { root } = subPageObj;
    (subPageObj.pages as IData[])
      .filter((page) => !key || page[key] === value)
      .forEach((page) => {
        subPages.push({
          ...page,
          path: `/${root}/${page.path}`,
        });
      });
  });
  const result = [...pages, ...subPages];
  return result;
};

/**
 * 计算注入属性
 * @param model
 * @param controller
 * @returns
 */
export function calcAttrs(
  model: IPanelItem,
  controller: IPanelItemController
): IParams {
  const attrs: IParams = {};
  model.controlAttributes?.forEach((item) => {
    if (item.attrName && item.attrValue) {
      attrs[item.attrName!] = ScriptFactory.execSingleLine(item.attrValue!, {
        ...controller.panel.getEventArgs(),
        data: controller.data,
      });
    }
  });
  return attrs;
}

export type RectResultType<T extends boolean> = T extends true
  ? UniApp.NodeInfo[]
  : UniApp.NodeInfo;

/**
 * 获取节点信息
 *
 * @export
 * @template T
 * @param {string} selector
 * @param {T} all
 * @param {*} [scope]
 * @return {*}  {Promise<RectResultType<T>>}
 */
export function getRect<T extends boolean>(
  selector: string,
  all: T,
  scope?: any
): Promise<RectResultType<T>> {
  return new Promise<RectResultType<T>>((resolve, reject) => {
    let query: UniNamespace.SelectorQuery | null = null;
    if (scope) {
      query = uni.createSelectorQuery().in(scope);
    } else {
      query = uni.createSelectorQuery();
    }
    query[all ? "selectAll" : "select"](selector)
      .boundingClientRect((rect) => {
        if (all && isArray(rect) && rect.length > 0) {
          resolve(rect as RectResultType<T>);
        } else if (!all && rect) {
          resolve(rect as RectResultType<T>);
        } else {
          reject(new Error("No nodes found"));
        }
      })
      .exec();
  });
}

/**
 * 转base64
 * - 适配微信小程序
 * @export
 * @param {string} str
 * @return {*}  {string}
 */
export function base64Encode(str: string): string {
  const CHARS =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  let out = "";
  let i = 0;
  const len = str.length;
  let c1;
  let c2;
  let c3;
  let enc1;
  let enc2;
  let enc3;
  let enc4;
  while (i < len) {
    c1 = str.charCodeAt(i++);
    c2 = str.charCodeAt(i++);
    c3 = str.charCodeAt(i++);
    enc1 = c1 >> 2;
    enc2 = ((c1 & 3) << 4) | (c2 >> 4);
    enc3 = ((c2 & 15) << 2) | (c3 >> 6);
    enc4 = c3 & 63;
    if (isNaN(c2)) {
      enc3 = enc4 = 64;
    } else if (isNaN(c3)) {
      enc4 = 64;
    }
    out +=
      CHARS.charAt(enc1) +
      CHARS.charAt(enc2) +
      CHARS.charAt(enc3) +
      CHARS.charAt(enc4);
  }
  return out;
}
